package cn.st4rlight.util.excel;

import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;

import org.apache.commons.lang3.time.StopWatch;

import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.google.common.collect.Lists;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * CSV工具类，大部分情况都推荐使用xlsx格式，csv格式很容易出问题
 *
 * @author st4rlight <st4rlight@163.com>
 * Created on 2025-05-06
 */
@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class EasyCSVUtil {

    /**
     * 读取csv文件
     */
    public static <T> List<T> readFromCSV(InputStream inputStream, Class<T> targetClz) {
        List<T> resultList = Lists.newArrayList();
        StopWatch stopWatch = StopWatch.createStarted();

        log.info("readFromCSV start targetClz: {}", targetClz.getName());
        AnalysisEventListener<T> eventListener = new AnalysisEventListener<>() {
            @Override
            public void invoke(T data, AnalysisContext context) {
                resultList.add(data);
            }
            @Override
            public void doAfterAllAnalysed(AnalysisContext context) {
                log.info("readFromCSV finished.");
            }
        };

        EasyExcelFactory.read(inputStream, targetClz, eventListener)
                .excelType(ExcelTypeEnum.CSV)
                .charset(StandardCharsets.UTF_8)
                .sheet().doRead();
        log.info("readFromCSV result size: {}, cost: {}ms", resultList.size(), stopWatch.getTime());
        return resultList;
    }

    /**
     * 导出csv文件
     */
    public static <T> void writeCSV(OutputStream outputStream, List<T> dataList, Class<T> headClass) {
        StopWatch stopWatch = StopWatch.createStarted();
        log.info("writeCSV size: {}", dataList.size());
        EasyExcelFactory.write(outputStream, headClass)
                .excelType(ExcelTypeEnum.CSV)
                .charset(StandardCharsets.UTF_8)
                .sheet().doWrite(dataList);
        log.info("writeCSV finished. cost: {}ms", stopWatch.getTime());
    }
}
